using System;

namespace HalconDotNet
{
	internal class HTupleElementsImplementation
	{
		protected int[] indices;

		protected HTupleImplementation source;

		public int[] I
		{
			get
			{
				return getI();
			}
			set
			{
				source.AssertSize(indices);
				setI(value);
			}
		}

		public long[] L
		{
			get
			{
				return getL();
			}
			set
			{
				source.AssertSize(indices);
				setL(value);
			}
		}

		public double[] D
		{
			get
			{
				return getD();
			}
			set
			{
				source.AssertSize(indices);
				setD(value);
			}
		}

		public string[] S
		{
			get
			{
				return getS();
			}
			set
			{
				source.AssertSize(indices);
				setS(value);
			}
		}

		public HHandle[] H
		{
			get
			{
				return getH();
			}
			set
			{
				source.AssertSize(indices);
				setH(value);
			}
		}

		public object[] O
		{
			get
			{
				return getO();
			}
			set
			{
				source.AssertSize(indices);
				setO(value);
			}
		}

		public HTupleType Type => getType();

		public int Length => indices.Length;

		public HTupleElementsImplementation()
		{
			source = null;
			indices = new int[0];
		}

		public HTupleElementsImplementation(HTupleImplementation source, int index)
		{
			this.source = source;
			indices = new int[1]
			{
				index
			};
		}

		public virtual void Dispose()
		{
		}

		public HTupleElementsImplementation(HTupleImplementation source, int[] indices)
		{
			this.source = source;
			this.indices = indices;
		}

		public int[] getIndices()
		{
			return indices;
		}

		public virtual int[] getI()
		{
			throw new HTupleAccessException(source);
		}

		public virtual long[] getL()
		{
			throw new HTupleAccessException(source);
		}

		public virtual double[] getD()
		{
			throw new HTupleAccessException(source);
		}

		public virtual string[] getS()
		{
			throw new HTupleAccessException(source);
		}

		public virtual HHandle[] getH()
		{
			throw new HTupleAccessException(source);
		}

		public virtual object[] getO()
		{
			throw new HTupleAccessException(source);
		}

		public virtual void setI(int[] i)
		{
			throw new HTupleAccessException(source);
		}

		public virtual void setL(long[] l)
		{
			throw new HTupleAccessException(source);
		}

		public virtual void setD(double[] d)
		{
			throw new HTupleAccessException(source);
		}

		public virtual void setS(string[] s)
		{
			throw new HTupleAccessException(source);
		}

		public virtual void setH(HHandle[] h)
		{
			throw new HTupleAccessException(source);
		}

		public virtual void setO(object[] o)
		{
			throw new HTupleAccessException(source);
		}

		protected bool IsValidArrayForSetX(Array a)
		{
			if (a == null)
			{
				return false;
			}
			if (a.Length != 1 && a.Length != indices.Length)
			{
				throw new HTupleAccessException(source, "Number of values must be one or match number of indexed elements");
			}
			return true;
		}

		public virtual HTupleType getType()
		{
			if (indices.Length == 0)
			{
				return HTupleType.EMPTY;
			}
			throw new HTupleAccessException(source);
		}
	}
}
